﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ReadeAssetManager
{
    public partial class frmSchedule : Form
    {
        private AMSServiceRef.ScheduleData _sched;
        private AMSServiceRef.Asset _asset;
        private AMSServiceRef.User _user;
        private const string INVALID_INPUT = "The title, date, and recurrance fields cannot be empty.  Please re-enter.";
        private const string VERIFY_DELETE = "You are about to delete this scheduled maintenance record.\n\n" +
                                             "Are you sure you want to delete this record?";
        private const string ERROR_LOAD_SCHED = "An error occurred while loading this schedule record.";
        private enum enumRecur { daily, weekly, monthly, annually };

        /// <summary>
        /// Constructor.
        /// This overload is used to create a new Schedule record.
        /// </summary>
        /// <param name="CurrentAsset">[AMSServiceRef.Asset] The asset record that will contain the new
        /// Schedule record.</param>
        public frmSchedule(AMSServiceRef.Asset CurrentAsset)
        {
            InitializeComponent();
            PopulateRecurranceOptions();
            _asset = CurrentAsset;
            _user = _asset.Owner;
            _sched = new AMSServiceRef.ScheduleData();
            _sched.BaseItem = _asset;
            this.Text = _asset.Name + " New Schedule";
        }

        /// <summary>
        /// Constructor.
        /// This overload is used to modify an existing Schedule record.
        /// </summary>
        /// <param name="CurrentSchedule">[AMSServiceRef.ScheduleData] The existing Schedule record to view
        /// or modify.</param>
        public frmSchedule(AMSServiceRef.ScheduleData CurrentSchedule)
        {
            InitializeComponent();
            PopulateRecurranceOptions();
            _sched = CurrentSchedule;
            _user = _sched.BaseItem.Owner;
            PopulateFormOptions();
            PopulateFormValues();
        }

        /// <summary>
        /// PopulateFormValues
        /// Fills the userform fields from the global AMSServiceRef.ScheduleData object.  Displays an
        /// error if the schedule data could not be accessed (such as the Schedule is not instantiated).
        /// </summary>
        private void PopulateFormValues()
        {
            try
            {
                txtTitle.Text = _sched.Title;
                txtComments.Text = _sched.Comments;
                dtpDue.Value = _sched.DateDue;
                FindScheduleRecurrance();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ERROR_LOAD_SCHED + "\n\n" + ex.Message, "Error Loading Schedule Record");
            }
        }

        /// <summary>
        /// PopulateRecurranceOptions
        /// Loads the default recurrance values to the recurrance combobox.
        /// </summary>
        private void PopulateRecurranceOptions()
        {
            cmbRecur.Items.Add(new ComboboxItem("Daily", 1));
            cmbRecur.Items.Add(new ComboboxItem("Weekly", 7));
            cmbRecur.Items.Add(new ComboboxItem("Monthly", 30));
            cmbRecur.Items.Add(new ComboboxItem("Annually", 365));
        }

        /// <summary>
        /// FindScheduleRecurrance
        /// Locates and shows in the combobox the recurrance value stored in the Schedule object.
        /// </summary>
        private void FindScheduleRecurrance()
        {
            foreach (ComboboxItem cbi in cmbRecur.Items)
            {
                if (cbi.Value == _sched.Recurrance)
                {
                    cmbRecur.SelectedItem = cbi;
                    return;
                }
            }
        }

        /// <summary>
        /// PopulateFormOptions
        /// Loads the form title and dropdown menu bar domains.
        /// </summary>
        private void PopulateFormOptions()
        {
            ToolStripMenuItem[] items;

            this.Text = _sched.BaseItem.Name + " Schedule: " + _sched.Title;

            // Load all available images
            if (_sched.Images != null)
            {
                items = new ToolStripMenuItem[_sched.Images.Count];
                for (int i = 0; i < _sched.Images.Count; i++)
                {
                    AMSServiceRef.AMSImage a = _sched.Images[i];
                    items[i] = CreateMenuItem(a, "mnuAssetImages" + a.ID, a.Caption, new EventHandler(LoadImageItem));
                }
                mnuSchedRecordsImages.DropDownItems.AddRange(items);
            }
            else
                _sched.Images = new List<AMSServiceRef.AMSImage>();
        }

        /// <summary>
        /// CreateMenuItem
        /// Creates a ToolStripMenuItem to represent the domain record for this Schedule.
        /// </summary>
        /// <param name="TagItem">[object] The domain object to be added to the MenuItem tag.</param>
        /// <param name="Name">[string] The MenuItem name.</param>
        /// <param name="Text">[string] The MenuItem text.</param>
        /// <param name="ClickEvent">[EventHandler] The event that should be raised when the user clicks the MenuItem.</param>
        /// <returns>[ToolStripMenuItem] The menu item representing this domain object.</returns>
        private ToolStripMenuItem CreateMenuItem(object TagItem, string Name,
                                                string Text, EventHandler ClickEvent)
        {
            ToolStripMenuItem tsmi = new ToolStripMenuItem();
            tsmi.Name = Name;
            tsmi.Text = Text;
            tsmi.Tag = TagItem;
            tsmi.Click += ClickEvent;

            return tsmi;
        }

        /// <summary>
        /// LoadImageItem
        /// EventHandler for an Image MenuItem.  This functionality is not implemented.
        /// </summary>
        /// <param name="sender">[object] The MenuItem that raised this event.</param>
        /// <param name="e">[EventArgs] The standard event arguments for a Click event.</param>
        private void LoadImageItem(object sender, EventArgs e)
        {
            // Open the images form with ((ToolStripMenuItem)sender).Tag
            MessageBox.Show("Images are not yet implemented.", "Not Implemented");
        }

        /// <summary>
        /// PopulateScheduleFromFields
        /// Loads all values from the userform into the current AMSServiceRef.ScheduleData object.
        /// </summary>
        private void PopulateScheduleFromFields()
        {
            _sched.Title = txtTitle.Text;
            _sched.DateDue = dtpDue.Value;
            _sched.Comments = txtComments.Text;
            if (cmbRecur.SelectedItem != null)
                _sched.Recurrance = ((ComboboxItem)cmbRecur.SelectedItem).Value;
        }

        /// <summary>
        /// SaveSchedule
        /// Validates the user input, hydrates the object from the userform controls, and attempts
        /// to save the schedule record.  If the save is successful, attempts to add a new ScheduleData 
        /// to the asset's schedules list and refreshes the frmMain asset list.
        /// </summary>
        /// <returns>[bool] True if the schedule record was successfully saved, otherwise false.</returns>
        private bool SaveSchedule()
        {
            if (IsValidInput())
            {
                PopulateScheduleFromFields();
                AMSServiceRef.AMSServiceClient c = new AMSServiceRef.AMSServiceClient();
                AMSServiceRef.ScheduleData tmps = c.SaveSchedule(_sched);
                if (tmps != null)
                {
                    _sched = tmps;
                    _user = _sched.BaseItem.Owner;
                    AddScheduleToAsset();
                    ((frmMain)this.MdiParent).RefreshAssetList(_user);
                    return true;
                }
                return false;
            }
            else
            {
                MessageBox.Show(INVALID_INPUT);
                return false;
            }
        }

        /// <summary>
        /// IsValidInput
        /// Validates the user input based on database requirements.
        /// </summary>
        /// <returns>[bool] True if the input is valid, otherwise false.</returns>
        private bool IsValidInput()
        {
            return (txtTitle.Text.Length > 0) &&
                   (cmbRecur.SelectedItem != null) &&
                   (dtpDue.Value != default(DateTime));
        }

        private void mnuSchedSchedSave_Click(object sender, EventArgs e)
        {
            if (!SaveSchedule())
                MessageBox.Show("Unable to save scheduled maintenance record.");
        }

        private void mnuSchedSchedSaveClose_Click(object sender, EventArgs e)
        {
            if (!SaveSchedule())
            {
                if (MessageBox.Show("Unable to save changes.  Do you still want to close?", "Save Failed", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No)
                    return;
            }
            this.Close();
        }

        private void mnuSchedRecordsImagesNew_Click(object sender, EventArgs e)
        {
            // New image handler
        }

        /// <summary>
        /// AddScheduleToAsset
        /// Determines whether this Schedule record already exists in the Asset.  If not, adds the Schedule
        /// record to the Asset schedules list.  Otherwise, simply returns.
        /// </summary>
        private void AddScheduleToAsset()
        {
            if (_sched.BaseItem.Schedules != null)
            {
                foreach (AMSServiceRef.ScheduleData s in _sched.BaseItem.Schedules)
                {
                    if (s.Equals(_sched))
                        return;
                }
            }
            else
                _sched.BaseItem.Schedules = new List<AMSServiceRef.ScheduleData>();

            _sched.BaseItem.Schedules.Add(_sched);
        }

        /// <summary>
        /// ComboboxItem
        /// A lightweight class to represent a combobox item.
        /// </summary>
        public class ComboboxItem
        {
            public ComboboxItem(string NewText, int NewValue)
            {
                Text = NewText;
                Value = NewValue;
            }
            public string Text { get; set; }
            public int Value { get; set; }

            public override string ToString()
            {
                return Text;
            }
        };

        private void mnuSchedSchedDelete_Click(object sender, EventArgs e)
        {
            if (_sched.ID > 0)
            {
                if (MessageBox.Show(VERIFY_DELETE, "Delete Scheduled Maintenance Record", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                {
                    AMSServiceRef.AMSServiceClient c = new AMSServiceRef.AMSServiceClient();
                    if (c.DeleteSchedule(_sched))
                    {
                        _sched.BaseItem.Schedules.Remove(_sched);
                        ((frmMain)MdiParent).RefreshAssetList(_user);
                        this.Close();
                    }
                    else
                        MessageBox.Show("Unable to delete scheduled maintenance record. " + _sched.Title);
                }
            }
        }
    }
}
